#include "characterclassform.h"
#include "ui_characterclassform.h"


#include <characterclass.h>


#include <QTreeView>
#include <QMenu>
#include <QDebug>


CharacterClassForm::CharacterClassForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CharacterClassForm)
{
    ui->setupUi(this);

    m_splitter = new QSplitter(this);
    layout()->addWidget(m_splitter);

    m_tabWidget = new QTabWidget(this);
    m_splitter->addWidget(m_tabWidget);

    m_tabWidget->tabBar()->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(m_tabWidget->tabBar(), &QTabBar::customContextMenuRequested, this, &CharacterClassForm::onCustomContextMenuRequested);
}

CharacterClassForm::~CharacterClassForm()
{
    delete ui;
}

void CharacterClassForm::setCampaign(Campaign *campaign)
{
    if (m_campaign.data() == campaign)
    {
        return;
    }

    m_campaign = campaign;

    while (m_splitter->count() > 1)
    {
        QWidget* w = m_splitter->widget(1);
        w->deleteLater();
    }

    while (m_tabWidget->count())
    {
        QWidget* w = m_tabWidget->widget(0);
        m_tabWidget->removeTab(0);
        w->deleteLater();
    }

    if (m_campaign.isNull())
    {
        return;
    }

    CharacterClasses* characterClasses = m_campaign->findChild<CharacterClasses*>(QString(), Qt::FindDirectChildrenOnly);

    foreach (CharacterClass* characterClass, characterClasses->findChildren<CharacterClass*>(QString(), Qt::FindDirectChildrenOnly))
    {
        QTreeView* treeView = new QTreeView(this);
        CharacterClassesModel* model = new CharacterClassesModel(treeView);

        connect(characterClass, &CharacterClass::sigChanged, this, &CharacterClassForm::onCharacterClassChanged);
        model->setRoot(characterClass);
        treeView->setModel(model);


        m_tabWidget->addTab(treeView, characterClass->name());


        treeView->hideColumn(1);
        treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
        treeView->setAlternatingRowColors(true);

        QModelIndex index = treeView->model()->index(0, 0, QModelIndex());
        while (index.isValid())
        {
            treeView->expand(index);
            index = index.sibling(index.row()+1, index.column());
        }
    }
}

void CharacterClassForm::onCharacterClassAdded()
{
    if (m_campaign.isNull())
    {
        return;
    }

    CharacterClasses* characterClasses = m_campaign->findChild<CharacterClasses*>(QString(), Qt::FindDirectChildrenOnly);
    QList<CharacterClassesModel*> models = m_splitter->findChildren<CharacterClassesModel*>();

    foreach (CharacterClass* characterClass, characterClasses->findChildren<CharacterClass*>(QString(), Qt::FindDirectChildrenOnly))
    {
        bool exists = false;
        foreach (CharacterClassesModel* model, models)
        {
            if (model->characterClass() == characterClass)
            {
                exists = true;
                break;
            }
        }

        if (exists)
        {
            continue;
        }

        // create tab

        QTreeView* treeView = new QTreeView(this);
        CharacterClassesModel* model = new CharacterClassesModel(treeView);
        connect(characterClass, &CharacterClass::sigChanged, this, &CharacterClassForm::onCharacterClassChanged);

        model->setRoot(characterClass);
        treeView->setModel(model);


        m_tabWidget->addTab(treeView, characterClass->name());


        treeView->hideColumn(1);
        treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
        treeView->setAlternatingRowColors(true);

        QModelIndex index = treeView->model()->index(0, 0, QModelIndex());
        while (index.isValid())
        {
            treeView->expand(index);
            index = index.sibling(index.row()+1, index.column());
        }
    }
}



void CharacterClassForm::onTabCloseRequested(int index)
{
    QTabWidget* tabWidget = qobject_cast<QTabWidget*>(sender());
    if (!tabWidget || tabWidget == m_tabWidget)
    {
        return;
    }

    QWidget* widget = tabWidget->widget(index);
    if (!widget)
    {
        return;
    }

    QString text = tabWidget->tabText(index);
    tabWidget->removeTab(index);

    m_tabWidget->addTab(widget, text);

    if (tabWidget->count() > 0)
    {
        return;
    }

    tabWidget->deleteLater();
}


void CharacterClassForm::onCustomContextMenuRequested(const QPoint &pos)
{
    qDebug() << Q_FUNC_INFO;

    QTabBar* tabBar = qobject_cast<QTabBar*>(sender());
    if (!tabBar)
    {
        qDebug() << Q_FUNC_INFO << "Not a tab bar";
        return;
    }

    QTabWidget* tabWidget = qobject_cast<QTabWidget*>(tabBar->parent());
    if (!tabWidget)
    {
        qDebug() << Q_FUNC_INFO << "Not a tab widget";
        return;
    }

    int index = tabBar->tabAt(pos);
    if (index < 0)
    {
        qDebug() << Q_FUNC_INFO << "Invalid tab index";
        return;
    }

    if (tabWidget == m_tabWidget && tabWidget->count() <= 1)
    {
        return;
    }

    QWidget* widget = tabWidget->widget(index);
    if (!widget)
    {
        qDebug() << Q_FUNC_INFO << "Not a widget";
        return;
    }

    QMenu menu;
    QAction* actSplit = 0;
    if (tabWidget->count() > 1)
    {
        actSplit = menu.addAction(tr("Split"));
    }

    if (m_splitter->count() > 1)
    {
        QMenu* sub = menu.addMenu(tr("Move"));
        for (int i = 0; i < m_splitter->count(); i++)
        {
            QTabWidget* w = qobject_cast<QTabWidget*>(m_splitter->widget(i));
            if (w == tabWidget)
            {
                continue;
            }

            QAction* act = sub->addAction(tr("%1").arg(i+1));
            act->setData(i);
        }
    }

    // todo: connects to tab bar instead of form!

    QAction* act = menu.exec(QCursor::pos());
    if (!act)
    {
        return;
    }

    QTabWidget* targetTabWidget = 0;

    if (act == actSplit)
    {
        targetTabWidget = new QTabWidget(this);
        targetTabWidget->setTabsClosable(true);
        connect(targetTabWidget, &QTabWidget::tabCloseRequested, this, &CharacterClassForm::onTabCloseRequested);

        targetTabWidget->tabBar()->setContextMenuPolicy(Qt::CustomContextMenu);
        connect(targetTabWidget->tabBar(), &QTabBar::customContextMenuRequested, this, &CharacterClassForm::onCustomContextMenuRequested);

        m_splitter->addWidget(targetTabWidget);
    }

    else
    {
        targetTabWidget = qobject_cast<QTabWidget*>(m_splitter->widget(act->data().toInt()));
    }

    if (!targetTabWidget)
    {
        return;
    }

    QString text = tabWidget->tabText(index);
    tabWidget->removeTab(index);
    targetTabWidget->addTab(widget, text);

    if (tabWidget != m_tabWidget && tabWidget->count() <= 0)
    {
        tabWidget->deleteLater();
    }

}

void CharacterClassForm::onCharacterClassChanged()
{
    foreach (QTabWidget* tabWidget, m_splitter->findChildren<QTabWidget*>(QString(), Qt::FindDirectChildrenOnly))
    {
        for (int i = 0; i < tabWidget->count(); i++)
        {
            QTreeView* view = qobject_cast<QTreeView*>(tabWidget->widget(i));
            if (!view)
            {
                continue;
            }

            CharacterClassesModel* model = qobject_cast<CharacterClassesModel*>(view->model());
            if (!model)
            {
                continue;
            }

            CharacterClass* cc = model->characterClass();
            if (!cc)
            {
                continue;
            }

            tabWidget->setTabText(i, cc->name());
        }
    }


}

